package com.basker.pisces.domain.validation.validator;

import java.util.List;

import org.apache.commons.lang3.ArrayUtils;

import com.basker.pisces.domain.entity.iterate.EntityIterateEvent;
import com.basker.pisces.domain.entity.iterate.EntityIterator;
import com.basker.pisces.domain.entity.iterate.IEntityIterateHandler;
import com.basker.pisces.domain.entity.meta.AbstractEntity;
import com.basker.pisces.domain.entity.meta.Entity;
import com.basker.pisces.domain.property.meta.TextProperty;
import com.basker.pisces.domain.validation.ValidationErrors;
import com.basker.pisces.domain.value.StringValue;

/**
 * 文本属性的值长度校验器
 *
 * @author hangwen
 */
public class StringValueLengthValidator extends AbstractValidator {

    @Override
    public ValidationErrors validate(Object[] dataObjects) {
        Entity entity = this.getEntity();

        ValidationErrors errors = new ValidationErrors();

        EntityIterator iterator = new EntityIterator(entity, dataObjects, new IterateHandler(errors));
        iterator.iterate();

        return errors;
    }

    private class IterateHandler implements IEntityIterateHandler {
        private ValidationErrors errors;

        public IterateHandler(ValidationErrors errors) {
            this.errors = errors;
        }

        @Override
        public void handle(EntityIterateEvent event) {
            AbstractEntity entity = event.getCurrentEntity();
            TextProperty[] textProperties = entity.getProperties().stream().filter(p -> p instanceof TextProperty)
                    .toArray(s -> new TextProperty[s]);

            if (ArrayUtils.isEmpty(textProperties)) {
                return;
            }

            List<Object> dataObjects = event.getDataObjects();

            for (Object dataObject : dataObjects) {
                for (TextProperty property : textProperties) {
                    StringValue stringValueObject = property.getValue(dataObject);
                    boolean valid = property.validateMaxLengh(stringValueObject);

                    if (!valid) {
                        errors.addError(property.createMaxLengthViolationError(dataObject, stringValueObject));
                    }
                }
            }
        }

    }

}
